import Transformation
from MatrixF import Matrix
from loadbin import Y, Cr, Cb
from Huffman import DC_L, DC_C, AC_C, AC_L, pointt

Y_M = Matrix(Y, 256, 256).transform(Transformation.M128)
Cr_M = Matrix(Cr, 256, 256).transform(Transformation.M128)
Cb_M = Matrix(Cb, 256, 256).transform(Transformation.M128)
# 将获得的YCrCb空间转化为三个矩阵，并且调整范围（-128）来进行下一步操作
# 保存量化矩阵
Q_Y = Matrix(
    [16, 11, 10, 16, 24, 40, 51, 61,
     12, 12, 14, 19, 26, 58, 60, 55,
     14, 13, 16, 24, 40, 57, 69, 56,
     14, 17, 22, 29, 51, 87, 80, 62,
     18, 22, 37, 56, 68, 109, 103, 77,
     24, 35, 55, 64, 81, 104, 113, 92,
     49, 64, 78, 87, 103, 121, 120, 101,
     72, 92, 95, 98, 112, 100, 103, 99]
    , 8, 8)
Q_C = Matrix(
    [17, 18, 24, 47, 99, 99, 99, 99,
     18, 21, 26, 66, 99, 99, 99, 99,
     24, 26, 56, 99, 99, 99, 99, 99,
     47, 66, 99, 99, 99, 99, 99, 99,
     99, 99, 99, 99, 99, 99, 99, 99,
     99, 99, 99, 99, 99, 99, 99, 99,
     99, 99, 99, 99, 99, 99, 99, 99,
     99, 99, 99, 99, 99, 99, 99, 99]
    , 8, 8)

subY = []
for x in range(256 * 256 // 8 // 8):#生成对象-->DCT-->量化-->保存到sub列
    subY.append(Matrix((Y_M.blocks(8, x)), 8, 8).transform(Transformation.DCT).division(Q_Y))
for x in range(256 * 256 // 8 // 8 - 1, 0, -1):
    subY[x].EigenArray[0][0] -= subY[x - 1].EigenArray[0][0]#差分
for x in range(256 * 256 // 8 // 8):
    subY[x] = subY[x].ZigZag()      #zigzag
    subY[x] = Transformation.RunLenthCoding(subY[x])    #游程编码
    subY[x][0] = DC_L[subY[x][0]]       #Huffman编码
    for y in range(len(subY[x])):
        if type(subY[x][y]) == tuple:
            subY[x][y] = AC_L[pointt(subY[x][y])]

subCR = []
for x in range(256 * 256 // 8 // 8):
    subCR.append(Matrix((Cr_M.blocks(8, x)), 8, 8).transform(Transformation.DCT).division(Q_C))
for x in range(256 * 256 // 8 // 8 - 1, 0, -1):
    subCR[x].EigenArray[0][0] -= subCR[x - 1].EigenArray[0][0]
for x in range(256 * 256 // 8 // 8):
    subCR[x] = subCR[x].ZigZag()
    subCR[x] = Transformation.RunLenthCoding(subCR[x])
    subCR[x][0] = DC_C[subCR[x][0]]
    for y in range(len(subCR[x])):
        if type(subCR[x][y]) == tuple:
            subCR[x][y] = AC_C[pointt(subCR[x][y])]

subCB = []
for x in range(256 * 256 // 8 // 8):
    subCB.append(Matrix((Cb_M.blocks(8, x)), 8, 8).transform(Transformation.DCT).division(Q_C))
for x in range(256 * 256 // 8 // 8 - 1, 0, -1):
    subCB[x].EigenArray[0][0] -= subCB[x - 1].EigenArray[0][0]
for x in range(256 * 256 // 8 // 8):
    subCB[x] = subCB[x].ZigZag()
    subCB[x] = Transformation.RunLenthCoding(subCB[x])
    subCB[x][0] = DC_C[subCB[x][0]]
    for y in range(len(subCB[x])):
        if type(subCB[x][y]) == tuple:
            subCB[x][y] = AC_C[pointt(subCB[x][y])]

finalresultl = []

for y in range(256 * 256 // 8 // 8):#拼合YCbCr再按照子矩阵拼合
    for x in [subY, subCB, subCR]:
        finalresultl.extend(x[y])


def run():      #运行
    return finalresultl

